package nl.cwi.arne.util;

import java.util.ArrayList;
import java.util.List;

import nl.cwi.arne.Network;
import nl.cwi.arne.NetworkActivation;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.workspace.AbstractEMFOperation;

/**
 * @generated NOT
 * @author Christian Krause
 */
public class NetworkActivationBuffer extends ArrayList<NetworkActivation> {
	
	// Default serial id.
	private static final long serialVersionUID = 1L;
	
	// Network.
	private Network network;
	
	// Editing domain (optional):
	private TransactionalEditingDomain editingDomain;

	// Commit interval.
	private int commitInterval = 10;
	
	// Number of added activations:
	private int added = 0;
	
	public NetworkActivationBuffer(Network network) {
		this.network = network;
	}
	
	/*
	 * (non-Javadoc)
	 * @see java.util.ArrayList#add(java.lang.Object)
	 */
	@Override
	public boolean add(NetworkActivation activation) {
		if (super.add(activation)) {
			added++;
			if (added<=commitInterval || size()>=commitInterval) {
				commit();
			}
			return true;
		} else {
			return false;
		}
	}
	
	public boolean commit() {
		if (isEmpty()) return false;
		final List<NetworkActivation> activations = this;
		runCommand(new Runnable() {
			public void run() {
				network.getActivations().addAll(activations);
				activations.clear();
			}
		});
		return true;
	}
	
	protected void runCommand(final Runnable runnable) {
		if (editingDomain!=null) {
			AbstractEMFOperation command = new AbstractEMFOperation(editingDomain, "Add activations") {
				@Override
				protected IStatus doExecute(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
					runnable.run();
					return Status.OK_STATUS;
				}
			};
			try {
				command.execute(new NullProgressMonitor(), null);
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
		} else {
			runnable.run();
		}
	}
	
	public void setCommitInterval(int interval) {
		this.commitInterval = interval;
	}
	
	public void setEditingDomain(TransactionalEditingDomain editingDomain) {
		this.editingDomain = editingDomain;
	}
}
